#include<stdio.h>
#include<string.h>
#define MAPSIZE 32
/*
*功能：作用于字符串_String，以包含在_Delimiter中的字符为分界符，将_String切分成一个个子串；
如果，_String为空值NULL，则函数保存的static指针SAVE_PTR在下一次调用中将作为起始位置。
参数： _String：指向欲分割的字符串；在第一次调用时，strtok()必需给予参数_String字符串，往后的调用则将参数_String设置成NULL；
	   _Delimiter:为分隔符字符（如果传入字符串，则传入的字符串中每个字符均为分割符）。
特点：strtok函数会破坏待分解字符串的完整性，调用前和调用后的_String已经不同。
*/						
char* __cdecl MyStrtok(char * _String, const char * _Delimiter)	
{
	//ASCII值是[0,255]；故而要进行无符号类型的强转。
	unsigned char *str;
	const unsigned char *ctrl = (const unsigned char *)_Delimiter;
	static unsigned char* SAVE_PTR = NULL; //如果_String为空值NULL，则函数保存的指针SAVE_PTR在下一次调用中将作为起始位置
	unsigned char map[MAPSIZE];	
	
	memset(map, 0, sizeof(char)*MAPSIZE);	//初始化标记数组
	do {
		//所有_Delimiter中包含的字符都会被做记号   或等于
		map[*ctrl >> 3] |= (1 << (*ctrl & 7)); //*ctrl>>3等效于*ctrl/8；*ctrl&7等效于*ctrl%8。
	} while (*ctrl++);
 
	if (_String != NULL)
		str = (unsigned char *)_String;		//第一次才满足if条件。
	else
		str = (unsigned char *)SAVE_PTR;
    
    //讨论：str ?= NULL，如果出现为NULL时，必定是else语句中的SAVE_PTR==NULL导致的；
    //SAVE_PTR始终指向上一次切割好的子串的结束符'\0'的下一位置，
    //如果SAVE_PTR == NULL，说明，主串遍历结束
    //警告：对空指针进行解引用是会崩溃的！！！
    //下行出现的if循环正常情况下并不起眼，
    //strtok函数到底调用几次是使用者控制的，如果字符串切割完成之后还继续调用呢？？？
    //必须终止！！！
    if(NULL == str) return NULL;
 
	//所有_Delimiter中包含的字符都会被滤掉，并将被滤掉的地方设为一处分割的节点。
	while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )		
		str++;
	_String = (char *)str;//_String指向 不包含在_Delimiter中的 首个字符 出现的位置----精华之处
 
	for (; *str; str++)
	{
		if ( map[*str >> 3] & (1 << (*str & 7)) )//扫描过程中发现_Delimiter中包含的分割字符时,则会将该字符改为'\0' 
		{
			*str++ = '\0';	//后续读取的时，遇到'\0'就停止；意味着破坏_String指向的字符串是不可避免的，充当结束符的角色
			break;
		}
	}
	SAVE_PTR = str;		//记下又一次出现_Delimiter中包含的字符的起始位置；
 
	return  _String;
}
 
int main()
{
	char str[] = { "192.168.0.10" };
	char *res[4] = { '\0'};
	res[0] = MyStrtok(str, ".");
	for (int i = 1; i < 4; ++i)
		res[i] = MyStrtok(NULL, ".");
 
	for (int i = 0; i < 4; ++i)
		printf("%s  ", res[i]);
	printf("\n");
	return 0;
}

{"success":"1","result":{"timestamp":"1560332753","datetime_1":"2019-06-12 17:45:53","datetime_2":"2019年06月12日 17时45分53秒","week_1":"3","week_2":"星期三","week_3":"周三","week_4":"Wednesday"}}
                                                           0p                       0                                          0p1          0

{"results":[{"location":{"id":"WWYMRT0VRMUG","name":"大连","country":"CN","path":"大连,大连,辽宁,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"晴","code":"1","temperature":"23"},"last_update":"2019-07-16T01:40:00+08:00"}]}
                                                                                                                                           0                 0                  0  0  0 0 0
http://api.k780.com/?app=weather.today&weaid=dalian&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
http://api.k780.com/?app=life.time&appkey=41298&sign=eb689df06015c995b73ae1f60c133a77&format=json